package com.xiaoyu.base.image;

import android.net.Uri;
import android.text.TextUtils;

import com.xiaoyu.base.BaseConstants;
import com.xiaoyu.base.utils.upload.UploadImageOriginalType;
import com.xiaoyu.base.utils.SharedPreferencesData;

import in.srain.cube.util.FilenameUtil;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

public class ImageUrlManager {

    public static final String HTTP = "http";
    public static final String HTTPS = "https";
    public static final String GIF = ".gif";

    public static final String ALIYUN_OSS_DOMAIN = "aliyuncs.com";
    public static final String QINIU_IMAGE_DOMAIN = "qiniu.com";
    public static final String QBOX_IMAGE_DOMAIN = "qbox.me";//also qiniu
    public static final String AMAP_IMAGE_DOMAIN = "amap.com";
    public static final String NEWSNS_YIZHOUCP_IMAGE_DOMAIN = "newsns.yizhoucp.cn";

    private static final String CHAR_QM = "?";
    private static final String CHAR_SHARP = "#";

    // private static final String KEY_IMAGEMOGR2 = "?imageMogr2";

    /**
     * Refer to: https://portal.qiniu.com/myTickets/ticketDetail?id=36037
     * There is one bug in qiniu.com, they may fail to convert gif to
     * animated webp.
     * So they suggested for now, add '/ignore-error/1' flag, if converting
     * failed,
     * The original image will be returned instead of one error msg.
     */
    private static final String QINIU_PROCESS_PATTEN_WEBP_WITH_QUALITY = "?imageView2/2/w/%s/format/webp/q/70/ignore-error/1";
    private static final String QINIU_PROCESS_PATTEN_WEBP = "?imageView2/2/w/%s/format/webp/ignore-error/1";
    private static final String QINIU_PROCESS_PATTEN = "?imageView2/2/w/%s/ignore-error/1";
    private static final String ALIYUN_OSS_PROCESS_PATTEN_WEBP = "?x-oss-process=image/resize,w_%s/format,webp";
    private static final String ALIYUN_OSS_PROCESS_PATTEN = "?x-oss-process=image/resize,w_%s";

    private static int[] sWidth = new int[]{1960, 1080, 960, 720, 640, 480, 320, 160, 80};
    private static ImageUrlManager sInstance;
    private Map<Integer, String> mCache;
    private Map<Integer, String> mQiniuCache;
    private boolean mIsNormalQuality;

    private ImageUrlManager() {
        mCache = new HashMap<>();
        mQiniuCache = new HashMap<>();
        mIsNormalQuality = SharedPreferencesData.basic().getBoolean(BaseConstants.SharedPreferencesKey.KEY_SETTINGS_PICTURE_QUALITY, true);
    }

    public synchronized static ImageUrlManager getInstance() {
        if (sInstance == null) {
            sInstance = new ImageUrlManager();
        }
        return sInstance;
    }

    public synchronized String getRemoteUrl(String url, int width, boolean keepOriginal) {
        return doGetRemoteUrl(url, width, keepOriginal);
    }

    public synchronized String getRemoteUrl(String url, int width) {
        return doGetRemoteUrl(url, width, false);
    }

    public synchronized void setNormalQuality(boolean normalQuality) {
        if (normalQuality != mIsNormalQuality) {
            mCache.clear();
        }
        mIsNormalQuality = normalQuality;
    }

    private String doGetRemoteUrl(String url, int width, boolean keepOriginal) {
        if (TextUtils.isEmpty(url)) {
            return "";
        }

        if (isLocalUrl(url)) {
            return processLocalUrl(url);
        }

        if (url.contains(NEWSNS_YIZHOUCP_IMAGE_DOMAIN) && url.contains(HTTPS)) {
            url = url.replace(HTTPS, HTTP);
        }

        if (isExternalUrl(url)) {
            return url;
        }

        int version_for_avatar = -1;
        // raw oss, record the version then put it back
        if (url.contains(ALIYUN_OSS_DOMAIN)) {
            try {
                String v = Uri.parse(url).getQueryParameter("v");
                if (!(TextUtils.isEmpty(v) || v.equals("null"))) {
                    version_for_avatar = (int) Double.parseDouble(v);
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        if (url.contains(CHAR_QM) || url.contains(CHAR_SHARP)) {
            url = url.split("\\?")[0].split(CHAR_SHARP)[0];
        }

        ImageLoadInfo imageLoadInfo = new ImageLoadInfo(url);
        boolean hasOriginal = imageLoadInfo.getOriginalType() == UploadImageOriginalType.ORIGINAL;
        if (keepOriginal && hasOriginal) {
            return url;
        }

        String extension = FilenameUtil.getExtensionFromUrl(url);
        boolean keepFormat = false;
        if (GIF.equals(extension)) {
            keepFormat = true;
            width = mIsNormalQuality ? width / 2 : width / 3;
        }

        if (!mCache.containsKey(width) || !mQiniuCache.containsKey(width)) {
            String postFix = "";
            for (int i = sWidth.length - 1; i >= 0; i--) {
                if (sWidth[i] >= width) {

                    int pictureWidth = sWidth[i];
                    if (!mIsNormalQuality && i < sWidth.length - 1) {
                        pictureWidth = sWidth[i + 1];
                    }

                    if (url.contains(NEWSNS_YIZHOUCP_IMAGE_DOMAIN)) {
                        String patten;
                        if (keepFormat) {
                            patten = QINIU_PROCESS_PATTEN;
                        } else if (hasOriginal) {
                            patten = QINIU_PROCESS_PATTEN_WEBP_WITH_QUALITY;
                        } else {
                            patten = QINIU_PROCESS_PATTEN_WEBP;
                        }
                        postFix = String.format(patten, pictureWidth);
                        mQiniuCache.put(width, postFix);
                    } else {
                        postFix = String.format(keepFormat ? ALIYUN_OSS_PROCESS_PATTEN : ALIYUN_OSS_PROCESS_PATTEN_WEBP, pictureWidth);
                        mCache.put(width, postFix);
                    }
                    break;
                }
            }
        }
        if (version_for_avatar == -1) {
            if (url.contains(NEWSNS_YIZHOUCP_IMAGE_DOMAIN)) {
                return url + mQiniuCache.get(width);
            } else {
                return url + mCache.get(width);
            }
        } else {
            if (url.contains(NEWSNS_YIZHOUCP_IMAGE_DOMAIN)) {
                return url + mQiniuCache.get(width) + "&v=" + version_for_avatar;
            } else {
                return url + mCache.get(width) + "&v=" + version_for_avatar;
            }
        }
    }

    public boolean isLocalUrl(String url) {
        return !url.startsWith(HTTP) && !url.startsWith(HTTPS);
    }

    public String processLocalUrl(String url) {
        if (url.startsWith("file://") || url.startsWith("res:/")) {
            return url;
        } else {
            return Uri.fromFile(new File(url)).toString();
        }
    }

    private boolean isExternalUrl(String url) {
        return url.contains(QINIU_IMAGE_DOMAIN) || url.contains(QBOX_IMAGE_DOMAIN) || url.contains(AMAP_IMAGE_DOMAIN);
    }
}
